package com.dh;

import com.dh.request.CopyIndexParam;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ESService {
    public static boolean isIndexExists(String indexName) {
        try {
            return ESTestClient.getClient().indices().exists(new GetIndexRequest(indexName), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void createIndex(String indexName){
        try {
            CreateIndexResponse response = ESTestClient.getClient().indices().create(new CreateIndexRequest(indexName), RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static IndexRequest buildIndexRequest(String index, Map<String,Object> obj, String id) {
        IndexRequest request = new IndexRequest(index);
        request.source(obj, XContentType.JSON);
        if(StringUtil.isNotBlank(id)) {
            request.id(id);
        }
        return request;
    }

    public static int add(String indexName,Map<String,Object> obj,String id) {
        IndexResponse index = null;
        try {
            index = ESTestClient.getClient().index(buildIndexRequest(indexName,obj,id), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return index.status().getStatus();
    }

    public static int updateById(String index,Map<String,Object> data,String id) {
        UpdateRequest request = new UpdateRequest();
        request.id(id);
        request.index(index);
        request.doc(data);
        try {
            UpdateResponse update = ESTestClient.getClient().update(request, RequestOptions.DEFAULT);
            return update.status().getStatus();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int bulk(String index, List<Map<String,Object>> data) {
        BulkRequest request = new BulkRequest(index);
        try {
            for (Map<String,Object> datum : data) {
                request.add(buildIndexRequest(index,datum,null));
            }
            BulkResponse bulk = ESTestClient.getClient().bulk(request, RequestOptions.DEFAULT);
            int status = bulk.status().getStatus();
            return status;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static Map<String, Object> queryById(String index, String id) {
        GetRequest request = new GetRequest(index);
        request.id(id);
        try {
            GetResponse response = ESTestClient.getClient().get(request, RequestOptions.DEFAULT);
            return response.getSourceAsMap();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void copyIndex(CopyIndexParam param) {
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        ssb.size(param.getSize());
        ssb.sort("_doc");
        SearchRequest request1 = new SearchRequest(param.getSourceIndex());
        Integer from = param.getFrom();
        if(null == from) {
            from = 0;
        }
        Integer to = param.getTo();
        if(null == to || to <= 0){
            to = Integer.MAX_VALUE;
        }
        Object[] searchAfter = null;
        while (true) {
            if (null != searchAfter) {
                ssb.searchAfter(searchAfter);
            }
            request1.source(ssb);
            SearchResponse search = null;
            try {
                search = ESTestClient.getClient().search(request1, RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            SearchHit[] hits = search.getHits().getHits();
            if(hits.length>0) {
                searchAfter = hits[hits.length-1].getSortValues();
                from += hits.length;

                List<Map<String,Object>> datas = new ArrayList<>();
                for (SearchHit hit : hits) {
                    datas.add(hit.getSourceAsMap());
                }
                int bulk = ESService.bulk(param.getTargetIndex(), datas);
                System.out.println(bulk);
            }else {
                break;
            }
            if(from >= to) {
                break;
            }
        }
    }
}
